package subprocess

import (
	"encoding/json"
	"io/ioutil"
	"os"
	"playbook/ginsvr/src/config"
	"playbook/ginsvr/src/global"
	"playbook/ginsvr/src/orm"
	"playbook/ginsvr/src/parsejson"
	"playbook/ginsvr/src/source/gene"
	"playbook/ginsvr/src/utils/fileutil"
	"playbook/ginsvr/src/utils/httputil"
	"playbook/ginsvr/src/utils/netutil"
	"playbook/ginsvr/src/utils/stringutil"
	"strings"

	"github.com/sirupsen/logrus"
)

/**
*  子流程复制
*  oldname：原子流程名称
*  name：新子流程名称
*  desc：新子流程描述
*  overtime： 新子流程超时时间
*  version： 新子流程版本
*  type: 0-子流程 1-编排
 */
func CopySubProcess(param map[string]interface{}) orm.Response {
	if param["name"] == nil || param["overtime"] == nil || param["version"] == nil || param["type"] == nil {
		return orm.Response{
			RespCode: "000001",
			RespMsg:  "子流程保存失败,参数不完整",
		}
	}
	//1.数据库新增数据
	//查询原子流程或编排信息
	var process orm.Process
	if param["type"].(string) == "0" {
		old := *orm.GetSubProcess(param["oldname"].(string))
		process = (old).SubProcess
	} else if param["type"].(string) == "1" {
		old := *orm.GetProcess(param["oldname"].(string))
		process = (old).Process
	} else {
		return orm.Response{
			RespCode: "000001",
			RespMsg:  "子流程保存失败,类型信息错误",
		}
	}

	if param["name"] != nil {
		process.Name = param["name"].(string)
	}
	if param["desc"] != nil {
		process.Desc = param["desc"].(string)
	}
	if param["overtime"] != nil {
		process.Overtime = param["overtime"].(string)
	}
	if param["version"] != nil {
		process.Version = param["version"].(string)
	}
	oldProjectid := process.Projectid
	process.Projectid = "fbb9e1b6b58f41eca9fd6d870d1c227a"
	data, _ := json.Marshal(&process)
	json.Unmarshal(data, &process)

	fullSubProcess := orm.FullSubProcess{SubProcess: process}
	str1 := stringutil.GetTitleStr(param["oldname"].(string))
	str2 := stringutil.GetTitleStr(param["name"].(string))

	//修改编排出入参
	params1 := process.Inputparameter["parameter"].(map[string]interface{})
	params1["name"] = "data"
	//修改classpath中名称
	params1["classPath"] = strings.Replace(params1["classPath"].(string), str1, str2, -1)
	params1["classPath"] = strings.Replace(params1["classPath"].(string), param["oldname"].(string), param["name"].(string), -1)
	//添加最外层和审计字段
	process.Inputparameter["parameter"] = getInputParam(params1)
	params2 := process.Outputparameter["parameter"].(map[string]interface{})
	params2["name"] = "data"
	params2["classPath"] = strings.Replace(params2["classPath"].(string), str1, str2, -1)
	params2["classPath"] = strings.Replace(params2["classPath"].(string), param["oldname"].(string), param["name"].(string), -1)
	process.Outputparameter["parameter"] = getOutputParam(params2)
	//修改原子服务
	for _, i := range process.Activities["activity"] {
		acti := i.(map[string]interface{})
		//补充表中没有的字段
		acti["alias"] = acti["name"]
		acti["flag"] = false

		if acti["type"] == float64(3) {
			continue
		}
		//出入参添加最外层和审计字段
		param1 := acti["input-parameter"].(map[string]interface{})["parameter"].(map[string]interface{})
		param1["name"] = "data"
		acti["input-parameter"] = map[string]interface{}{"parameter": getInputParam(param1)}
		param2 := acti["output-parameter"].(map[string]interface{})["parameter"].(map[string]interface{})
		param2["name"] = "data"
		acti["output-parameter"] = map[string]interface{}{"parameter": getOutputParam(param2)}
	}
	//数据库中新增子编排
	res := orm.AddSubprocess(fullSubProcess)
	switch res.(type) {
	case error:
		return orm.Response{RespCode: "000001",
			RespMsg: "子流程保存失败，数据库新增失败"}
	case orm.Response:
		return orm.Response{RespCode: "000001",
			RespMsg: "子流程保存失败，数据库新增失败"}
	}

	//生成编排和循环出入参类
	genebeanlist := []orm.GenebeanParammsg{}
	if res.(map[string]interface{})["genebeanmsgList"] != nil {
		genebeanlist = res.(map[string]interface{})["genebeanmsgList"].([]orm.GenebeanParammsg)
	}

	for _, genebeanmsg := range genebeanlist {
		if genebeanmsg.Inparamid != "" {
			gene.GeneParamBean("composebean", res.(map[string]interface{})["processname"].(string), genebeanmsg.Inparamid, genebeanmsg.Subpath)
		}
		if genebeanmsg.Outparamid != "" {
			gene.GeneParamBean("composebean", res.(map[string]interface{})["processname"].(string), genebeanmsg.Outparamid, genebeanmsg.Subpath)
		}
	}

	//子流程json保存
	parsejson.SaveSubProcessJson(fullSubProcess)
	err := copyOriginJson(param["oldname"].(string), oldProjectid, param["type"].(string), process.Name)

	if err != nil {
		return orm.Response{RespCode: "000001",
			RespMsg: "子流程保存失败,复制前端json文件失败"}
	}

	//处理脚本和循环
	for _, i := range process.Activities["activity"] {
		acti := i.(map[string]interface{})
		//如果是脚本，复制脚本代码和出入参
		if acti["type"] == float64(2) {
			newfiles := getScriptPath(process.Name + "." + acti["name"].(string))
			oldfiles := getScriptPath(param["oldname"].(string) + "." + acti["name"].(string))
			if len(newfiles) > 0 {
				//本地复制脚本类文件和出参文件
				fileutil.CopyFile(newfiles[0], oldfiles[0])
				fileutil.CopyFile(newfiles[1], oldfiles[1])
				ip, err := netutil.ExternalIP()
				if err != nil {
					global.LOG.WithFields(logrus.Fields{
						"err": err,
					}).Error("子流程保存失败,获取本地IP失败")
					return orm.Response{RespCode: "000001",
						RespMsg: "子流程保存失败,获取本地IP失败"}
				}
				//服务器复制脚本类文件和出参文件
				err = httputil.ScriptCopy(httputil.CopyContent{IP: ip.String(),
					Newpath: newfiles,
					Oldpath: oldfiles})
				if err != nil {
					global.LOG.WithFields(logrus.Fields{
						"err": err,
					}).Error("子流程保存失败,服务器脚本复制失败.")
					return orm.Response{RespCode: "000001",
						RespMsg: "子流程保存失败,服务器脚本复制失败"}
				}
			}

		}

	}
	return orm.Response{RespCode: "000000",
		RespMsg: "子流程保存成功"}
}

func getInputParam(oldparam map[string]interface{}) map[string]interface{} {
	newparam := map[string]interface{}{}

	con := config.GetConfig("auditfiled").(map[string]interface{})
	params := []interface{}{oldparam}
	pp := con["inputFixedParams"].([]map[string]interface{})
	for _, p := range pp {
		params = append(params, p)
	}

	newparam["classPath"] = "com.psbc.cbcbp.base.inner.InnerReqDTO"
	newparam["mappingname"] = "InnerReqDTO"
	newparam["name"] = "InnerReqDTO"
	newparam["optional"] = "false"
	newparam["parameter"] = params
	newparam["type"] = "Map"
	return newparam
}

func getOutputParam(oldparam map[string]interface{}) map[string]interface{} {
	newparam := map[string]interface{}{}

	con := config.GetConfig("auditfiled").(map[string]interface{})

	params := []interface{}{oldparam}
	pp := con["outputFixedParams"].([]map[string]interface{})
	for _, p := range pp {
		params = append(params, p)
	}

	newparam["classPath"] = "com.psbc.cbcbp.base.inner.InnerRespDTO"
	newparam["mappingname"] = "InnerRespDTO"
	newparam["name"] = "InnerRespDTO"
	newparam["optional"] = "false"
	newparam["parameter"] = params
	newparam["type"] = "Map"
	return newparam
}

func copyOriginJson(oldname string, projectid string, processtype string, newname string) error {

	//查询原origin.json文件路径
	var oldpath string
	newprocess := &orm.GetSubProcess(newname).SubProcess

	if processtype == "0" {
		//oldpath = orm.GetGeneSrcDefine("composejson").Srcpath + global.PTHSEP + "subprocess"
		oldpath = parsejson.GetJsonPath(projectid, true).Srcpath
	} else {
		//oldpath = orm.GetGeneSrcDefine("composejson").Srcpath
		oldpath = parsejson.GetJsonPath(projectid, false).Srcpath
	}
	localpath := orm.GetLocalPath("00001").LocalPath
	//配置路径/编排服务名/origin.json
	oldpath = localpath + global.PTHSEP + oldpath + global.PTHSEP + oldname + global.PTHSEP + "origin.json"

	jsonFile, err := os.Open(oldpath)
	if err != nil {
		global.LOG.WithFields(logrus.Fields{
			"err": err,
		}).Error("error opening json file")
		return err
	}
	defer jsonFile.Close()

	//读取原origin.json文件
	jsonData, err := ioutil.ReadAll(jsonFile)
	if err != nil {
		global.LOG.WithFields(logrus.Fields{
			"err": err,
		}).Error("error reading json file")
		return err
	}

	var data map[string]interface{}
	err = json.Unmarshal(jsonData, &data)
	if err != nil {
		global.LOG.WithFields(logrus.Fields{
			"err": err,
		}).Error("error ummarshal json")
		return err
	}
	cells := []interface{}{}
	//替换原json中编排服务id和名称
	for _, cell := range data["cells"].([]interface{}) {

		if eachMap, ok := cell.(map[string]interface{}); ok {

			switch eachMap["shape"] {
			case "image":
				// var circleStruct parsejson.Circle
				// //转存circle结构体
				// temp, _ := json.Marshal(cell)
				// json.Unmarshal(temp, &circleStruct)
				// if circleStruct.Data.Type == "Start" {
				// 	circleStruct.Data.Name = newname
				// 	circleStruct.Data.Id = newprocess.Processid
				// 	circleStruct.Data.Desc = newprocess.Desc
				// 	circleStruct.Data.Version = newprocess.Version
				// 	//将项目id设置成子流程的项目id
				// 	circleStruct.Data.Projectid = "fbb9e1b6b58f41eca9fd6d870d1c227a"
				// }
				// temp, _ = json.Marshal(circleStruct)
				// json.Unmarshal(temp, &cell)
				data := eachMap["data"].(map[string]interface{})
				if data["type"] == "Start" {
					data["name"] = newname
					data["id"] = newprocess.Processid
					data["desc"] = newprocess.Desc
					data["version"] = newprocess.Version
					data["projectid"] = "fbb9e1b6b58f41eca9fd6d870d1c227a"
					eachMap["data"] = data
				}
			}
			cells = append(cells, cell)
		}
	}

	//保存原始json
	parsejson.SaveOriginJson(cells, false)
	return nil
}

/**
* 获取脚本文件路径
 */
func getScriptPath(actname string) []string {

	gsd := orm.GetGeneSrcDefine("script")
	if gsd.Srcpath == "" {
		return []string{}
	}

	snlst := strings.Split(actname, ".")
	srcpath := fileutil.SepTransform(gsd.Srcpath + global.PTHSEP + strings.TrimSpace(snlst[0]))

	return []string{srcpath + global.PTHSEP + snlst[1] + ".java", srcpath + global.PTHSEP + snlst[1] + "Out.java"}
}

/**
*  生成出入参文件
 */
func geneParamBean(genetype string, pname string, genebeanmsg orm.GenebeanParammsg, projectpath string) {

	if genebeanmsg.Inparamid != "" {
		gene.GeneParamBean(genetype, pname, genebeanmsg.Inparamid, genebeanmsg.Subpath)
	}
	if genebeanmsg.Outparamid != "" {
		gene.GeneParamBean(genetype, pname, genebeanmsg.Outparamid, genebeanmsg.Subpath)
	}

}
